home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
SGI Developer Toolbox 6.1
/
SGI Developer Toolbox 6.1 - Disc 4.iso
/
public
/
SciAn
/
src
/
ScianLights.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-08-01
|
18KB
|
802 lines
/*ScianLights.c
Lights
Eric Pepke
May 21, 1991
*/
#include "Scian.h"
#include "ScianTypes.h"
#include "ScianColors.h"
#include "ScianLists.h"
#include "ScianArrays.h"
#include "ScianWindows.h"
#include "ScianSpaces.h"
#include "ScianDraw.h"
#include "ScianObjWindows.h"
#include "ScianVisWindows.h"
#include "ScianVisObjects.h"
#include "ScianIcons.h"
#include "ScianIDs.h"
#include "ScianControls.h"
#include "ScianButtons.h"
#include "ScianErrors.h"
#include "ScianDialogs.h"
#include "ScianSliders.h"
#include "ScianTextBoxes.h"
#include "ScianStyle.h"
#include "ScianComplexControls.h"
#include "ScianLights.h"
#include "ScianMethods.h"
#include "ScianScripts.h"
#include "ScianEvents.h"
#include "ScianObjFunctions.h"
#include "ScianSymbols.h"
#include "ScianFontSystem.h"
ObjPtr lightClass; /*Class of individual light*/
int lightsNum = 0;
ObjPtr commonLights = NULLOBJ;
Bool lastTwoSided = false; /*Last change to twoSided*/
int nTotalLights = 0;
#define TOTALLIGHTS 8 /*Total number of possible lights*/
#define NLIGHTS 2 /*Number of lights available by default*/
lightSpec defLights[] =
{
{(M_PI_4 * 1.2), M_PI_4, {1.0, 1.0, 1.0}, 1.0, false},
/*{M_PI_2, M_PI_4, {0.7, 1.0, 1.0}, 0.5, false},*/
{-M_PI_4, - 0.7 * M_PI_4, {0.7, 1.0, 1.0}, 0.5, false},
{M_PI, M_PI_4, {1.0, 0.0, 0.5}, 0.2, true},
{0.0, M_PI_2, {1.0, 1.0, 0.6}, 0.3, true}
};
#ifdef GRAPHICS
/*Don't change this without checking references*/
float lightModel[] = {
AMBIENT, 0.2, 0.2, 0.2,
#ifdef TWOSIDE
TWOSIDE, 0.0,
#endif
LMNULL};
#endif
#ifdef PROTO
void TwoSided(Bool whether)
#else
void TwoSided(whether)
Bool whether;
#endif
/*Goes to two sided lighting on whether*/
{
#ifdef GRAPHICS
{
if (whether != lastTwoSided)
{
int k;
lastTwoSided = whether;
if (whether)
{
/*Bind all the reverse lights*/
for (k = 0; k < nTotalLights; ++k)
{
if (rgbp)
{
lmbind(LIGHT0 + k + nTotalLights, k * 2 + 2);
}
}
}
else
{
/*Unbind all the reverse lights*/
for (k = 0; k < nTotalLights; ++k)
{
if (rgbp)
{
lmbind(LIGHT0 + k + nTotalLights, 0);
}
}
}
}
}
#endif
}
#ifdef PROTO
void StartLights(ObjPtr space, ObjPtr lights, Bool twoSided)
#else
void StartLights(space, lights, twoSided)
ObjPtr space, lights;
Bool twoSided;
#endif
/*Starts the lights*/
{
ThingListPtr runner;
int k;
#ifdef GRAPHICS
if (rgbp)
{
lmbind(LMODEL, 1);
}
#endif
runner = LISTOF(lights);
k = 0;
while (runner)
{
ObjPtr light;
ObjPtr var;
real brightness;
real baseColor[3];
real location[3];
#ifdef GRAPHICS
float tempLight[50];
float *lightPtr;
#endif
light = runner -> thing;
if (k < TOTALLIGHTS && !GetPredicate(runner -> thing, HIDDEN))
{
var = GetVar(light, BRIGHTNESS);
if (var && IsReal(var))
{
brightness = GetReal(var);
}
else
{
brightness = 1.0;
}
var = GetVar(light, BASECOLOR);
if (var)
{
Array2CArray(baseColor, var);
}
else
{
baseColor[0] = 1.0;
baseColor[1] = 1.0;
baseColor[2] = 1.0;
}
var = GetFixedArrayVar("StartLights", light, LOCATION, 1, 3L);
if (!var)
{
return;
}
Array2CArray(location, var);
#ifdef GRAPHICS
lightPtr = tempLight;
*lightPtr++ = POSITION;
*lightPtr++ = location[0];
*lightPtr++ = location[1];
*lightPtr++ = location[2];
*lightPtr++ = 0.0;
*lightPtr++ = LCOLOR;
*lightPtr++ = baseColor[0] * brightness;
*lightPtr++ = baseColor[1] * brightness;
*lightPtr++ = baseColor[2] * brightness;
*lightPtr++ = LMNULL;
if (rgbp)
{
lmdef(DEFLIGHT, k * 2 + 1, 0, tempLight);
lmbind(LIGHT0 + k, k * 2 + 1);
}
{
/*Make the reverse light*/
lightPtr = tempLight;
*lightPtr++ = POSITION;
*lightPtr++ = -location[0];
*lightPtr++ = -location[1];
*lightPtr++ = -location[2];
*lightPtr++ = 0.0;
*lightPtr++ = LCOLOR;
*lightPtr++ = baseColor[0] * brightness;
*lightPtr++ = baseColor[1] * brightness;
*lightPtr++ = baseColor[2] * brightness;
*lightPtr++ = LMNULL;
if (rgbp)
{
lmdef(DEFLIGHT, k * 2 + 2, 0, tempLight);
}
}
#endif
++k;
}
runner = runner -> next;
}
nTotalLights = k;
}
void StopLights(space)
ObjPtr space;
/*Stops lights in space*/
{
int k;
#ifdef GRAPHICS
for (k = 0; k < TOTALLIGHTS; ++k)
{
if (rgbp)
{
lmbind(LIGHT0 + k, 0);
}
}
if (rgbp)
{
lmbind(LMODEL, 0);
}
#endif
}
ObjPtr NewLight(k)
int k;
/*Returns a new light with default definition k*/
{
ObjPtr light;
ObjPtr baseColor;
ObjPtr name;
ObjPtr loc;
real *locPtr;
light = NewObject(lightClass, 0);
/*Set light position*/
loc = NewRealArray(1, 3L);
locPtr = ArrayMeat(loc);
*locPtr++ = rcos(defLights[k] . theta) * rcos(defLights[k] . phi);
*locPtr++ = rsin(defLights[k] . theta) * rcos(defLights[k] . phi);
*locPtr++ = rsin(defLights[k] . phi);
SetVar(light, LOCATION, loc);
/*Set light color*/
baseColor = NewRealArray(1, 3L);
CArray2Array(baseColor, defLights[k] . baseColor);
SetVar(light, BASECOLOR, baseColor);
/*Set light brightness*/
SetVar(light, BRIGHTNESS, NewReal(defLights[k] . brightness));
/*Set whether the light is enabled or not*/
SetVar(light, HIDDEN, NewInt(defLights[k] . enabled));
name = GetVar(lightClass, NAME);
if (name)
{
sprintf(tempStr, "%s %d", GetString(name), ++lightsNum);
}
else
{
sprintf(tempStr, "Light %d", ++lightsNum);
}
name = NewString(tempStr);
SetVar(light, NAME, name);
SetVar(light, SPACES, NewList());
return light;
}
ObjPtr NewLights()
/*Returns a new list of lights*/
{
ObjPtr lights;
int k;
if (oneLights)
{
if (commonLights) return commonLights;
}
lights = NewList();
for (k = 0; k < NLIGHTS; ++k)
{
ObjPtr light;
light = NewLight(k);
/*Set the light's parent*/
SetVar(light, PARENT, lights);
PostfixList(lights, light);
}
return lights;
}
static ObjPtr CloneLight(light)
ObjPtr light;
/*Clones a light light*/
{
ObjPtr newLight;
newLight = NewLight(0);
CopyVar(newLight, light, LOCATION);
CopyVar(newLight, light, BASECOLOR);
CopyVar(newLight, light, BRIGHTNESS);
CopyVar(newLight, light, HIDDEN);
return newLight;
}
static ObjPtr BindLightToSpace(light, space)
ObjPtr light, space;
/*Makes space know about a light.*/
{
ObjPtr lightsList;
lightsList = GetVar(space, LIGHTS);
if (!lightsList)
{
lightsList = NewList();
SetVar(space, LIGHTS, lightsList);
}
PrefixList(lightsList, light);
SetVar(light, PARENT, space);
if (ListCount(lightsList) > TOTALLIGHTS)
{
char errmes[256];
sprintf(errmes, "Only %d lights can be shown.\n", TOTALLIGHTS);
ReportError("BindLightToSpace", errmes);
}
return ObjTrue;
}
static ObjPtr HideLight(light)
ObjPtr light;
/*Hides a light*/
{
SetVar(light, HIDDEN, ObjTrue);
ImInvalid(light);
return ObjTrue;
}
static ObjPtr ShowLight(light)
ObjPtr light;
/*Shows a light*/
{
SetVar(light, HIDDEN, ObjFalse);
ImInvalid(light);
return ObjTrue;
}
static ObjPtr lightForRGB;
static void LightRGB(visWindow)
WinInfoPtr visWindow;
/*Sends a deferred message to visWindow if it has lightForRGB*/
{
ObjPtr space;
ObjPtr lights;
space = FindSpace(visWindow);
if (space)
{
lights = GetVar(space, LIGHTS);
if (lights)
{
ThingListPtr runner;
runner = LISTOF(lights);
while (runner)
{
if (runner -> thing == lightForRGB)
{
DeferMessage((ObjPtr) visWindow, SETRGBMESSAGE);
return;
}
runner = runner -> next;
}
}
}
}
static ObjPtr ShowLightControls(object, windowName)
ObjPtr object;
char *windowName;
/*Makes a new control window to control light*/
{
WinInfoPtr controlWindow;
ObjPtr var;
ObjPtr panel;
ObjPtr contents;
ObjPtr lights;
ThingListPtr runner;
ObjPtr firstIcon = 0;
WinInfoPtr dialogExists;
int k;
dialogExists = DialogExists((WinInfoPtr) object, NewString("Controls"));
controlWindow = GetDialog((WinInfoPtr) object, NewString("Controls"), windowName,
LWINWIDTH, LWINHEIGHT, LWINWIDTH, LWINHEIGHT, WINUI + WINFIXEDSIZE);
SetVar((ObjPtr) controlWindow, HELPSTRING,
NewString("This window shows controls for a light source at infinity."));
#ifdef GRAPHICS
if (hasRGB)
{
lightForRGB = object;
ForAllVisWindows(LightRGB);
}
#endif
if (!dialogExists)
{
ObjPtr control, checkBox, corral, sw, textBox, slider, icon, colorObj;
ObjPtr var, button;
int width, left, right, bottom, top, cellHeight, m1, m2;
SetVar((ObjPtr) controlWindow, REPOBJ, object);
/*Add in a panel*/
panel = NewPanel(greyPanelClass, 0, LWINWIDTH, 0, LWINHEIGHT);
if (!panel)
{
return ObjFalse;
}
contents = GetVar((ObjPtr) controlWindow, CONTENTS);
PrefixList(contents, panel);
SetVar(panel, PARENT, (ObjPtr) controlWindow);
contents = NewList();
SetVar(panel, CONTENTS, contents);
width = LWINWIDTH - 2 * CORRALBORDER;
left = MAJORBORDER;
cellHeight = COLORWHEELWIDTH;
/*Precalculate the midlines for convenience*/
m1 = LWINHEIGHT - MAJORBORDER - cellHeight / 2;
left += COLORWHEELWIDTH + MAJORBORDER;
/*Create the color control*/
control = NewColorWheel(left - COLORWHEELWIDTH - MAJORBORDER, left - MAJORBORDER,
m1 - COLORWHEELWIDTH / 2,
m1 + COLORWHEELWIDTH / 2, "Color");
SetVar(control, HELPSTRING, NewString("This color wheel controls the base color of a light. \
It will only have an effect if the window containing the light is in full color mode."));
PrefixList(contents, control);
SetVar(control, PARENT, panel);
AssocColorControlWithVar(control, object, BASECOLOR);
var = GetFixedArrayVar("ShowLightControls", object, BASECOLOR, 1, 3L);
if (!var)
{
real *baseColor;
var = NewRealArray(1, 3L);
baseColor = ELEMENTS(var);
baseColor[0] = 1.0;
baseColor[1] = 1.0;
baseColor[2] = 1.0;
SetVar(object, BASECOLOR, var);
}
/*Create the text box*/
textBox = NewTextBox(left - COLORWHEELWIDTH - MAJORBORDER - 30, left - MAJORBORDER + 30,
m1 - cellHeight / 2 - TEXTBOXSEP - TEXTBOXHEIGHT,
m1 - cellHeight / 2 - TEXTBOXSEP,
0, "Color Text", "Color");
PrefixList(contents, textBox);
SetVar(textBox, PARENT, panel);
SetTextAlign(textBox, CENTERALIGN);
left += MAJORBORDER;
/*Create the brightness slider*/
var = GetRealVar("ShowLightControls", object, BRIGHTNESS);
if (!var)
{
SetVar(object, BRIGHTNESS, NewReal(1.0));
}
slider = NewSlider(left, left + SLIDERWIDTH,
m1 - cellHeight / 2, m1 + cellHeight / 2,
PLAIN, "Brightness");
SetVar(slider, HELPSTRING, NewString("This slider controls the brightness \
of the light. It will only have an effect if the window containing the light is in full color mode."));
if (!slider)
{
return ObjFalse;
}
PrefixList(contents, slider);
SetVar(slider, PARENT, panel);
SetSliderRange(slider, 1.0, 0.0, 0.0);
AssocDirectControlWithVar(slider, object, BRIGHTNESS);
/*Create the brightness text box*/
textBox = NewTextBox(left - MAJORBORDER - MINORBORDER, left + SLIDERWIDTH + MINORBORDER + MAJORBORDER,
m1 - cellHeight / 2 - TEXTBOXSEP - TEXTBOXHEIGHT,
m1 - cellHeight / 2 - TEXTBOXSEP,
0, "Brightness Text", "Brightness");
PrefixList(contents, textBox);
SetVar(textBox, PARENT, panel);
SetTextAlign(textBox, CENTERALIGN);
}
return (ObjPtr) controlWindow;
}
#define LIGHTDSPSTEP 0.1 /*Step to display outward for lights*/
static real globalLightRadius;
ObjPtr DrawLight(light)
ObjPtr light;
/*Draws a light in a space*/
{
float lightrad = 1.0;
if (IsSelected(light))
{
ObjPtr var;
real brightness;
real baseColor[3];
real location[3];
float clr[3];
real azimuth;
real xyrange;
real elevation;
lightrad += LIGHTDSPSTEP;
var = GetVar(light, BRIGHTNESS);
if (var && IsReal(var))
{
brightness = GetReal(var);
}
else
{
brightness = 1.0;
}
var = GetVar(light, BASECOLOR);
if (var)
{
Array2CArray(baseColor, var);
}
else
{
baseColor[0] = 1.0;
baseColor[1] = 1.0;
baseColor[2] = 1.0;
}
var = GetFixedArrayVar("DrawLights", light, LOCATION, 1, 3L);
if (!var)
{
return;
}
Array2CArray(location, var);
/*Calculate the azimuth*/
if (location[0] == 0.0 && location[1] == 0.0)
{
azimuth = 0.0;
}
else
{
azimuth = atan2(location[1], location[0]);
}
/*Calculate the xyrange and elevation*/
xyrange = (float) sqrt(location[0] * location[0] + location[1] * location[1]);
elevation = atan2(location[2], xyrange);
if (elevation >= M_PI) elevation -= 2 * M_PI;
SetLineWidth(2);
SetUIColor(UIGRAY50);
/*Draw the horizon circle*/
{
NudgeFarther();
NudgeFarther();
#ifdef GRAPHICS
circ(0.0, 0.0, globalLightRadius);
#endif
NudgeCloser();
NudgeCloser();
}
/*Draw the X space line*/
SetUIColor(UIWHITE);
DrawSpaceLine(0.0, 0.0, 0.0, lightrad * globalLightRadius, 0.0, 0.0);
/*Choose a color for subsequent stuff*/
#ifdef GRAPHICS
clr[0] = baseColor[0] * (brightness * 0.8 + 0.2);
clr[1] = baseColor[1] * (brightness * 0.8 + 0.2);
clr[2] = baseColor[2] * (brightness * 0.8 + 0.2);
if (rgbp)
{
c3f(clr);
}
else
{
color(uiColorIndex[ClosestUIColor(clr)]);
}
#endif
/*Draw the azimuth measurement*/
sprintf(tempStr, "%4.0f deg.", (float) azimuth * 180.0 / M_PI);
SetUIFont(UIBOLDLARGEFONT);
DrawSpaceString((lightrad + 0.05) * globalLightRadius * rcos(azimuth * 0.5),
(lightrad + 0.05) * globalLightRadius * rsin(azimuth * 0.5),
0.0,
tempStr);
#ifdef GRAPHICS
/*Draw the azimuth circle*/
if (azimuth < 0.0)
{
arc(0.0, 0.0, lightrad * globalLightRadius, azimuth * 1800.0 / M_PI, 0);
}
else
{
arc(0.0, 0.0, lightrad * globalLightRadius, 0, azimuth * 1800.0 / M_PI);
}
#endif
/*Draw the azimuth line*/
DrawSpaceLine(0.0, 0.0, 0.0, lightrad * globalLightRadius * rcos(azimuth), lightrad * globalLightRadius * sin(azimuth), 0.0);
#ifdef GRAPHICS
/*Draw the elevation arc*/
pushmatrix();
rotate(900, 'x');
rot(azimuth * 180.0 / M_PI, 'y');
if (elevation < 0.0)
{
arc(0.0, 0.0, lightrad * globalLightRadius, elevation * 1800.0 / M_PI, 0);
}
else
{
arc(0.0, 0.0, lightrad * globalLightRadius, 0, elevation * 1800.0 / M_PI);
}
#endif
/*Draw the elevation measurement*/
sprintf(tempStr, "%4.0f deg.", (float) elevation * 180.0 / M_PI);
SetUIFont(UIBOLDLARGEFONT);
DrawSpaceString((lightrad + 0.05) * globalLightRadius * rcos(elevation * 0.5),
(lightrad + 0.05) * globalLightRadius * sin(elevation * 0.5),
0.0,
tempStr);
#ifdef GRAPHICS
popmatrix();
#endif
SetLineWidth(3);
DrawSpaceLine(0.0, 0.0, 0.0, 30.0 * location[0],
30.0 * location[1],
30.0 * location[2]);
SetLineWidth(1);
}
}
#ifdef PROTO
void DrawLights(ObjPtr space, ObjPtr lights, int action, real radius)
#else
void DrawLights(space, lights, action, radius)
ObjPtr space, lights;
int action;
real radius;
#endif
/*Draw lights in space if they want to be displayed
Action is DRAWSPACE, PICKSPACE, etc.
Radius is radius of sphere in center area*/
{
#ifdef GRAPHICS
ThingListPtr runner;
zbuffer(FALSE);
globalLightRadius = radius;
runner = LISTOF(lights);
while (runner)
{
ObjPtr light;
DrawObject(runner -> thing);
runner = runner -> next;
}
zbuffer(TRUE);
#endif
}
static ObjPtr DeleteLightIcon(icon)
ObjPtr icon;
/*Deletes a light object associated with an icon*/
{
ObjPtr space, contents;
ObjPtr repObj;
repObj = GetObjectVar("DeleteLightIcon", icon, REPOBJ);
if (!repObj)
{
return ObjFalse;
}
space = GetVar(icon, SPACE);
if (!space)
{
return ObjFalse;
}
SetVar(repObj, SPACE, NULLOBJ);
contents = GetListVar("DeleteVisObjectIcon", space, LIGHTS);
if (!contents)
{
return ObjFalse;
}
DeleteFromList(contents, repObj);
ImInvalid(space);
return ObjTrue;
}
static ObjPtr MakeLightAppearance(light)
ObjPtr light;
/*Dummy make for light appearance*/
{
SetVar(light, APPEARANCE, ObjTrue);
ImInvalid(light);
return ObjTrue;
}
void InitLights()
{
ObjPtr icon;
ObjPtr list;
#ifdef GRAPHICS
lmdef(DEFLMODEL, 1, 0, lightModel);
#endif
/*Create class of lights*/
lightClass = NewObject(controllerClass, 0);
AddToReferenceList(lightClass);
SetMethod(lightClass, BINDTOSPACE, BindLightToSpace);
SetMethod(lightClass, NEWCTLWINDOW, ShowLightControls);
SetVar(lightClass, DOUBLECLICK, NewString(OF_SHOW_CONTROLS));
SetMethod(lightClass, HIDE, HideLight);
SetMethod(lightClass, SHOW, ShowLight);
list = NewList();
PrefixList(list, NewSymbol(HIDDEN));
SetVar(lightClass, SNAPVARS, list);
SetMethod(lightClass, CLONE, CloneLight);
SetMethod(lightClass, DRAW, DrawLight);
SetVar(lightClass, CLASSID, NewInt(CLASS_LIGHT));
DeclareDependency(lightClass, APPEARANCE, SELECTED);
SetMethod(lightClass, APPEARANCE, MakeLightAppearance);
icon = NewIcon(0, 0, ICONLIGHTS, "Light");
SetVar(icon, HELPSTRING,
NewString("This icon represents a light. When this icon is selected, \
a ray showing the direction and color of the light will appear in the space. \
You can rotate the light by pressing and dragging in the space with the center \
mouse button. You can show the controls for the light, such as the brightness and \
color, by selecting it and choosing the Show Controls item in the Object menu.\n\
\nYou can drag the light icon to the corral of another visualization \
window to have it illuminate that space as well. A space can hold up to eight lights. \
The easiest way to add additional lights is to select a light and choose Duplicate from \
the Object menu."));
SetMethod(icon, DELETEICON, DeleteLightIcon);
SetMethod(lightClass, DUPLICATE, DuplicateSpaceObject);
SetMethod(lightClass, DELETE, DeleteObject);
SetVar(lightClass, DEFAULTICON, icon);
SetVar(lightClass, NAME, NewString("Light"));
}
void KillLights()
{
DeleteThing(lightClass);
}